home *** CD-ROM | disk | FTP | other *** search
- /* time_routines.c
- AmigaDos supplies us with a Delay() function we can use in our
- programs which takes an argument in 1/50ths or 1/60ths of a second.
- This is too coarse grained, and is dependent on which country the
- Amiga is in. A better way to wait a specified amount of time
- is using the timer.device.
- Copyright © 1993 Robert Poole
- */
-
- #include <exec/types.h>
- #include <exec/io.h>
- #include <exec/memory.h>
- #include <devices/timer.h>
-
- #include <clib/exec_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/dos_protos.h>
-
- #include <stdlib.h>
- #include <stdio.h>
-
- #include "time_routines.h"
-
- struct timerequest *TimerIO = NULL;
- struct timerequest *TimeQueue[NUM_TIME_SLOTS];
- struct MsgPort *TimerPort = NULL;
-
- /* int setup_timer(void)
- sets up all the necessary stuff for the timer.device
- returns TRUE if successful, FALSE otherwise */
-
- int setup_timer(void)
- {
- int i, j;
-
- /* message port for communicating with timer device */
- TimerPort = CreateMsgPort();
- if (TimerPort == NULL) {
- return(FALSE);
- }
- /* our primary IO structure */
- TimerIO = (struct timerequest *) CreateExtIO(TimerPort,
- sizeof(struct timerequest));
- if (TimerIO == NULL) {
- DeleteMsgPort(TimerPort);
- return(FALSE);
- }
-
- /* open the timer device and initialize it */
- if (OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *) TimerIO,
- 0L)) {
- DeleteMsgPort(TimerPort);
- DeleteExtIO((struct IORequest *) TimerIO);
- return(FALSE);
- }
-
- /* set up a primitive queue structure so we can make multiple requests */
- for (i = 0; i < NUM_TIME_SLOTS; i++) {
- TimeQueue[i] = (struct timerequest *) AllocMem(sizeof(struct timerequest),
- MEMF_PUBLIC | MEMF_CLEAR);
- if (TimeQueue[i] == NULL) {
- if (i > 0) {
- for (j = 0; j < i; j++) {
- FreeMem((void *) TimeQueue[j], sizeof(struct timerequest));
- }
- }
- CloseDevice((struct IORequest *) TimerIO);
- DeleteMsgPort(TimerPort);
- DeleteExtIO((struct IORequest *) TimerIO);
- return(FALSE);
- }
-
- *TimeQueue[i] = *TimerIO;
- }
-
- /* success! */
- return(TRUE);
- }
- /* end: setup_timer() */
-
- /* void dispose_timer_resources(void)
- deallocate any and all allocated timer resources */
-
- void dispose_timer_resources(void)
- {
- int i;
-
- CloseDevice((struct IORequest *) TimerIO);
- DeleteMsgPort(TimerPort);
- DeleteExtIO((struct IORequest *) TimerIO);
- for (i = 0; i < NUM_TIME_SLOTS; i++) {
- FreeMem((void *) TimeQueue[i], sizeof(struct timerequest));
- }
- }
- /* end: dispose_timer_resources() */
-
- /* void synchronous_wait(unsigned long secs, unsigned long microsecs)
- wait for specified amount of time and then return */
-
- void synchronous_wait(unsigned long secs, unsigned long microsecs)
- {
- struct timeval tv_temp;
-
- tv_temp.tv_secs = secs;
- tv_temp.tv_micro = microsecs;
-
- TimerIO->tr_node.io_Command = TR_ADDREQUEST;
- TimerIO->tr_time = tv_temp;
-
- DoIO((struct IORequest *) TimerIO);
- }
- /* end: synchronous_wait() */
-
- /* void asynchronous_wait(unsigned long secs, unsigned long microsecs)
- same as synchronous_wait(), except that it returns immediately
- the program can then go about its business, then call
- wait_asynch_finish() to wait for the timer request to finish */
-
- void asynchronous_wait(unsigned long secs, unsigned long microsecs)
- {
- struct timeval tv_temp;
-
- tv_temp.tv_secs = secs;
- tv_temp.tv_micro = microsecs;
-
- TimerIO->tr_node.io_Command = TR_ADDREQUEST;
- TimerIO->tr_time = tv_temp;
-
- SendIO((struct IORequest *) TimerIO);
- }
- /* end: asynchronous_wait() */
-
- /* void wait_asynch_finish(void)
- wait for an asynchronously started timer request to finish */
-
- void wait_asynch_finish(void)
- {
- WaitIO((struct IORequest *) TimerIO);
- }
- /* end: wait_asynch_finish() */
-
- /* void queue_asynch_wait(int slot, unsigned long secs, unsigned long microsecs)
- queue a request to wait in the given slot */
-
- void queue_asynch_wait(int slot, unsigned long secs, unsigned long microsecs)
- {
- /* check first to make sure we're in a valid slot range */
- if (slot > NUM_TIME_SLOTS) {
- return;
- }
- /* send off a request */
- TimeQueue[slot]->tr_node.io_Command = TR_ADDREQUEST;
- TimeQueue[slot]->tr_time.tv_secs = secs;
- TimeQueue[slot]->tr_time.tv_micro = microsecs;
- SendIO((struct IORequest *) TimeQueue[slot]);
- }
- /* end: queue_asynch_wait() */
-
- /* int queue_next_finish(void)
- wait for the next event in the time queue to end */
-
- int queue_next_finish(void)
- {
- int i;
- struct Message *timer_msg;
-
- WaitPort(TimerPort);
- timer_msg = GetMsg(TimerPort);
- /* match the next event to complete */
- for (i = 0; i < NUM_TIME_SLOTS; i++) {
- if (timer_msg == (struct Message *) TimeQueue[i]) {
- return(i);
- }
- }
- }
- /* end: queue_next_finish() */
-